package main

import (
	"fmt"
	"net"
	"strings"
)

type User struct {
	Name string
	Addr string
	C    chan string
	conn net.Conn

	// server 指针
	server *Server
}

// 创建用户
func NewUser(conn net.Conn, server *Server) *User {
	user := &User{
		Name:   conn.RemoteAddr().String(),
		Addr:   conn.RemoteAddr().String(),
		C:      make(chan string),
		conn:   conn,
		server: server,
	}

	// 监听 User channel
	go user.ListenMessage()

	return user
}

// 监听 user channel
// 给客户端发送消息
func (this *User) ListenMessage() {
	for {
		msg := <-this.C

		this.conn.Write([]byte(msg + "\n"))
	}
}

// 用户上线
func (this *User) Online() {
	// 新增用户到 OnlineMap
	this.server.mapLock.Lock()
	this.server.OnlineMap[this.Name] = this
	this.server.mapLock.Unlock()

	// 发送用户上线的广播
	this.server.BroadCast(this, Str2GBK("已上线"))
}

// 用户下线
func (this *User) Offline() {
	// 用户从 OnlineMap 删除
	this.server.mapLock.Lock()
	delete(this.server.OnlineMap, this.Name)
	this.server.mapLock.Unlock()

	// 发送用户上线的广播
	this.server.BroadCast(this, Str2GBK("下线了"))

}

// 给当前客户端发送消息
func (this *User) SendMsg(msg string) {
	this.conn.Write([]byte(Str2GBK(msg + "\n")))
}

// 用户处理消息
func (this *User) DoMessage(msg string) {
	command := strings.Split(msg, "|")
	switch command[0] {
	case "who":
		// 查询在线用户
		repMsg := "以下用户在线："
		for key := range this.server.OnlineMap {
			repMsg += (key + "、")
		}
		// 中文字符长度为 3
		this.SendMsg(repMsg[:len(repMsg)-3])
	case "rename":
		// 更改用户姓名
		if len(command) < 2 {
			this.SendMsg("消息格式不正确")
			return
		}
		newName := Str2UTF8(command[1])

		this.server.mapLock.Lock()
		// 判断用户名是否已存在
		_, ok := this.server.OnlineMap[newName]
		if ok {
			this.server.mapLock.Unlock()
			this.SendMsg("当前用户名已存在")
			return
		}

		fmt.Println(this.Name, "更名为", newName)
		delete(this.server.OnlineMap, this.Name)
		this.Name = newName
		this.server.OnlineMap[newName] = this
		this.server.mapLock.Unlock()
	case "to":
		// 私聊
		if len(command) < 3 {
			this.SendMsg("消息格式不正确")
			return
		}
		userName := command[1]
		talkMsg := command[2]

		this.server.mapLock.Lock()
		// 判断用户是否存在
		sendUser, ok := this.server.OnlineMap[userName]
		this.server.mapLock.Unlock()
		if !ok {
			// 用户不存在
			this.SendMsg("该用户名不存在")
			return
		}
		// 用户存在，发送消息
		sendUser.SendMsg("[" + this.Name + "]对你说: " + talkMsg)
	default:
		// 将消息进行广播
		this.server.BroadCast(this, msg)
	}
}
